var/_math/Math = new()
_math
	proc

		// Title: Arc Tangent Snippet
		// Credit to: Lummox JR
		// Contributed by: Jtgibson
		// http://www.byond.com/members/Jtgibson/forum?id=8
		Atan2(x, y)
			if(!x && !y) return 0
			var/a = arccos(x / sqrt(x*x + y*y))
			return y >= 0 ? a : -a

		Ceiling(x, interval = 1)
			return interval == 1 ? -round(-x) : Ceiling(x / interval, 1) * interval

		Clamp(val, min, max)
			return max(min, min(val, max))

		// nCr - Returns the number of ways to pick r items from a pool of n items, where order doesn't matter.
		Combinations(n, r)
			return Factorial(n) / (Factorial(n - r) * Factorial(r))

		// cotangent
		Cot(x)
			return 1 / Tan(x)

		// cosecant
		Csc(x)
			return 1 / sin(x)

		Default(a, b)
			return a ? a : b

		Factorial(x)
			ASSERT(IsInteger(x) && x >= 0)
			if(x == 0)
				return 1
			. = x
			while(x > 2)
				. *= --x

		Floor(x, interval = 1)
			return interval == 1 ? round(x) : Floor(x / interval) * interval

		// Greatest Common Divisor - Euclid's algorithm
		Gcd(a, b)
			return b ? Gcd(b, a % b) : a

		Inverse(x)
			return 1 / x

		IsAboutEqual(a, b, deviation = 0.1)
			return abs(a - b) <= deviation

		IsEven(x)
			return x % 2 == 0

		// Returns true if val is from min to max, inclusive.
		IsInRange(val, min, max)
			return min <= val && val <= max

		IsInteger(x)
			return Floor(x) == x

		IsOdd(x)
			return !IsEven(x)

		// Least Common Multiple
		Lcm(a, b)
			return abs(a) / Gcd(a, b) * abs(b)

		// Performs a linear interpolation between a and b.
		// Note that amount=0 returns a, amount=1 returns b, and
		// amount=0.5 returns the mean of a and b.
		Lerp(a, b, amount = 0.5)
			return a + (b - a) * amount

		Mean(...)
			var
				values 	= 0
				sum		= 0
			for(var/val in args)
				values++
				sum += val
			return sum / values

		// nPr - Returns the number of ways to pick r items from a pool of n items, where order does matter.
		Permutations(n, r)
			return Factorial(n) / Factorial(n - r)

		// Returns the nth root of x.
		Root(n, x)
			return x ** (1 / n)

		// secant
		Sec(x)
			return 1 / cos(x)

		Slope(x1, y1, x2, y2)
			return (y1 - y2) / (x1 - x2)

		// The quadratic formula. Returns a list with the solutions, which will be numbers or /Complex types.
		// (Solves ax**2 + bx + c = 0 for x.)
		SolveQuadratic(a, b, c)
			ASSERT(a)
			. = list()
			var
				d		= b*b - 4 * a * c
				bottom  = 2 * a
				root	= sqrt(abs(d))
			if(d < 0)
				. += new/Complex(-b / bottom,  root / bottom)
				. += new/Complex(-b / bottom, -root / bottom)
			else
				. += (-b + root) / bottom
				if(d)
					. += (-b - root) / bottom

		// tangent
		Tan(x)
			return sin(x) / cos(x)

		ToDegrees(radians)
						  // 180 / Pi
			return radians * 57.2957795

		ToRadians(degrees)
						  // Pi / 180
			return degrees * 0.0174532925

		// min is inclusive, max is exclusive
		Wrap(val, min, max)
			var
				d = max - min
				t = Floor((val - min) / d)
			return val - (t * d)

	var/const
		Tau		= 6.28318531 // tau = 2*Pi
		Pi 		= 3.14159265
		E		= 2.71828183
		Sqrt2	= 1.41421356